﻿using System;
using System.Configuration;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Wicresoft.SelfService.DAO;
using Wicresoft.SelfService.BL;
using Wicresoft.SelfService.BL.Interface;
using MySql.Data.MySqlClient;
using System.Data;
using Wicresoft.SelfService.Portal.Models;
using NRemedy;

namespace Wicresoft.SelfService.Portal.Controllers
{
    public class AccountController : BaseController
    {
        public static string _cookieKey = null;

        public IFormsAuthenticationService FormsService { get; set; }

        protected override void Initialize(RequestContext requestContext)
        {
            if (FormsService == null) { FormsService = new mockFormsAuthenticationService(); }
            base.Initialize(requestContext);
        }
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult LogOn(string returnUrl)
        {
            if (string.IsNullOrEmpty(returnUrl))
                return View();
            else
            {
                if (_cookieKey == null)
                {
                    //get cookie key
                    _cookieKey = "fj-itsm-sso";//System.Configuration.ConfigurationManager.AppSettings["SSOCookie"];
                }

                //not set SSOCookie config,don't try SSO Authentication
                if (string.IsNullOrEmpty(_cookieKey)) return View();

                //try get cookie
                var cookie = Request.Cookies[_cookieKey];
                //SSO cookie exsit
                if (cookie != null)
                {
                    //auto logon and 301 to returnUrl
                    string ming = selfDecrypt(cookie.Value, 3);
                    FormsService.SignIn(ming.Substring(0, ming.IndexOf('|', 0)), false);

                    return Redirect(returnUrl);
                }
                return View();
            }
            
        }
        
        public ActionResult LogOut()
        {
            FormsService.SignOut();
            return RedirectToAction("LogOn", "Account");
        }

        public ViewResult ChangeInfo()
        {
            AccountInfo ai = null;
            try
            {
                ITServiceHelper helper = new ITServiceHelper();
                List<UserInfo> uis = helper.getUserInfoByAccountID(User.Identity.Name);
                UserInfo ui = uis.First();
                ai = new AccountInfo();
                ai.Account = ui.accountID;
                ai.Mail = ui.email;
                ai.Company = ui.company;
                ai.Dept = ui.dept;
                ai.Phone = ui.phone;
                ai.Position = ui.position;

            }
            catch
            {
                ai = null;
            }
            ViewData["IsChanged"] = false;
            return View(ai);
        }

        [HttpPost]
        public ViewResult ChangeInfo(AccountInfo ai)
        {
            if (ai == null)
            {
                return View(ai);
            }

            //change account info into the following system
            //1.selfservice
            //2.itportal
            //3.itsm
            //99.ldap mysql

            ViewData["Error1"] = "自服务平台更新失败，请重试，或联系管理员！";
            ViewData["Error2"] = "ITSM平台更新失败，请重试，或联系管理员！";
            ViewData["Error3"] = "信息化运维管理系统更新失败，请重试，或联系管理员！";

            //--serlservice account update
            ITServiceHelper helper = new ITServiceHelper();
            if (helper.UpdateUserAccountInfo(ai) == false)
            {
                //ViewData["Error1"] = "自服务系统更新失败，请重试，或联系管理员！";
                return View(ai);
            }
            ViewData["Error1"] = null;
            
            //--ITSM
            if (ITSMUpdateUserAccountInfo(ai) == false)
            {
                //ViewData["Error"] = "IT运维管理系统更新失败，请重试，或联系管理员！";
                return View(ai);
            }
            ViewData["Error2"] = null;

            //--itportal
            if (helper.UpdateUserAccountInfoToITPortal(ai) == false)
            {
                return View(ai);
            }
            ViewData["Error3"] = null;

            //--ldap pwd change
            if (ai.NewPassword != ai.ConfirmPassword)
            {
                ViewData["Error0"] = "新密码和确认密码不一致，请重新输入！";
                return View(ai);
            }

            if (!string.IsNullOrEmpty(ai.NewPassword) && !string.IsNullOrEmpty(ai.ConfirmPassword))
            {
                if (ChangePassword(ai.Account, ai.NewPassword) != 1)
                {
                    ViewData["Error4"] = "密码修改失败，请重试！";
                    return View(ai);
                }
            }

            ViewData["Error4"] = null;
            ViewData["IsChanged"]=true;
            return View(ai);

        }

        [HttpPost]
        public ActionResult LogOn(LogOnModel model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                if (FormsService.ValidateUser(model.UserName, model.Password))
                {
                    FormsService.SignIn(model.UserName, model.RememberMe);
                    if (Url.IsLocalUrl(returnUrl))
                    {
                        return Redirect(returnUrl);
                    }
                    else
                    {
                        return RedirectToAction("Index", "ITService");
                    }
                }
                else
                {
                    ModelState.AddModelError("", "用户名或密码错误");
                }
            }

            return View(model);
        }

        //[HttpPost]
        public ActionResult SSO(string redirectionUrl)
        {
            var context = this.HttpContext;
            if (context != null)
            {
                HttpCookie httpcookie = new HttpCookie("fj-itsm-sso", selfEncrypt(User.Identity.Name + "|User@123",3));
                string orignalDomain = context.Request.ServerVariables["SERVER_NAME"].ToString();
                if (orignalDomain.Contains('.'))
                {
                    int begin = orignalDomain.IndexOf('.') + 1;
                    httpcookie.Domain = orignalDomain.Substring(begin);
                    httpcookie.Path = "/";
                }
                //httpcookie.Domain = context.Request.ServerVariables["SERVER_NAME"].ToString();
                context.Response.Cookies.Add(httpcookie);
            }
            else
            {
                return RedirectToAction("SSOFailed");
            }
            return Redirect(redirectionUrl);

        }

        private string selfEncrypt(string input, int key)
        {
            if (string.IsNullOrEmpty(input))
                return input;

            string HexStr = string.Empty;

            List<int> orgint = new List<int>();

            for (int i = 0; i < input.Length; i++)
            {
                int asc_char = Convert.ToInt32(input[i]);
                orgint.Add(asc_char - 3);
            }

            for (int j = 0; j < orgint.Count() - 1; j++)
            {
                orgint[j + 1] = orgint[j] ^ orgint[j + 1];
            }

            for (int k = 0; k < orgint.Count(); k++)
            {
                HexStr += orgint[k].ToString("X02");
            }


            return HexStr;
        }

        public ActionResult SSOFailed()
        {
            return View();
        }

        private int ChangePassword(string login, string pass)
        {
            if (string.IsNullOrEmpty(login)) return 0;
            MySqlConnection conn = null;
            int ret = 1;
            try
            {
                conn = new MySqlConnection(ConfigurationManager.AppSettings["Mysql"]);
                conn.Open();
                MySqlCommand command2 = conn.CreateCommand();
                command2.CommandType = CommandType.Text;
                command2.CommandText = @" update persons p set password=@password  where p.name=@name";
                var passP = new MySqlParameter("password", MySqlDbType.String, 100);
                passP.Value = pass;
                var nameP = new MySqlParameter("name", MySqlDbType.String, 100);
                nameP.Value = login;

                command2.Parameters.Add(passP);
                command2.Parameters.Add(nameP);

                ret = command2.ExecuteNonQuery();
            }
            catch (Exception e)
            {
                ret = 0;
            }
            finally
            {
                if(conn != null)
                    conn.Close();
            }
            return ret;
        }

        private bool ITSMUpdateUserAccountInfo(AccountInfo ai)
        {
            bool ret = false;
            //skip null uid
            if (string.IsNullOrEmpty(ai.Account))
                return false;
            var context = new ARLoginContext(ConfigurationManager.AppSettings["ARServer"], 
                ConfigurationManager.AppSettings["ARUid"], 
                ConfigurationManager.AppSettings["ARPwd"]);
            try
            {
                var _server = new ARProxy<CTMPeople>(context);
                ARProxy<CTMPeople> ctmPeopleARProxy = new ARProxy<CTMPeople>(context);
                string querystr = string.Format("\'4\'=\"{0}\"", ai.Account);
                var exitPeople = ctmPeopleARProxy.GetEntryByQuery(querystr);
                if (exitPeople.Count > 0)
                {

                    var source = exitPeople[0];
                    //if (!string.Equals(employee.COMPANY, source.Company)) source.Company = employee.COMPANY;
                    if (!string.Equals(ai.Dept, source.Department)) source.Department = ai.Dept;
                    //if (!string.Equals(employee.CNAME[0].ToString(), source.FirstName)) source.FirstName = employee.CNAME[0].ToString();
                    //if (!string.Equals(employee.CNAME, source.FullName)) source.FullName = employee.CNAME;
                    //if (!string.Equals(employee.CNAME.Substring(1), source.LastName)) source.LastName = employee.CNAME.Substring(1);
                    if (!string.Equals(ai.Phone, source.PhoneNumberBusiness)) source.PhoneNumberBusiness = ai.Phone;
                    if (!string.Equals(ai.Position, source.JobTitle)) source.JobTitle = ai.Position;
                    if (!string.Equals(ai.Mail, source.InternetEmail)) source.InternetEmail = ai.Mail;

                    context.ServerInstance.SetEntry("CTM:People", source.Request_ID, new ModelBinder<CTMPeople>().UnBindForUpdate(source));

                    //ctmPeopleARProxy.SetEntry(source);
                    ret = true;
                }
            }
            catch
            {
                ret = false;
            }
            finally
            {
                context.Dispose();
            }
            return ret;
            
        }

        private string selfDecrypt(string input, int key)
        {
            if (string.IsNullOrEmpty(input))
                return input;

            string orgstr = string.Empty;

            int i;
            List<int> encryptInt = new List<int>();
            for (i = input.Length - 2; i >= 0; i -= 2)
            {
                encryptInt.Insert(0, Convert.ToInt32(input.Substring(i, 2), 16));
            }

            for (i = encryptInt.Count() - 1; i >= 1; i--)
            {
                encryptInt[i] = encryptInt[i] ^ encryptInt[i - 1];
            }

            for (i = 0; i < encryptInt.Count(); i++)
            {
                encryptInt[i] = encryptInt[i] + key;
                orgstr += Convert.ToChar(encryptInt[i]);
            }

            return orgstr;
        }

    }
}
